home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / nt / emacssrc.zip / EMACSSRC.TAR / emacs-19.17 / lisp / paren.el < prev    next >
Lisp/Scheme  |  1993-07-23  |  4KB  |  125 lines

  1. ;;; paren.el --- highlight matching paren.
  2. ;; Copyright (C) 1993 Free Software Foundation, Inc.
  3.  
  4. ;; Author: rms@gnu.ai.mit.edu
  5. ;; Maintainer: FSF
  6. ;; Keywords: languages, faces
  7.  
  8. ;; This file is part of GNU Emacs.
  9.  
  10. ;; GNU Emacs is free software; you can redistribute it and/or modify
  11. ;; it under the terms of the GNU General Public License as published by
  12. ;; the Free Software Foundation; either version 2, or (at your option)
  13. ;; any later version.
  14.  
  15. ;; GNU Emacs is distributed in the hope that it will be useful,
  16. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. ;; GNU General Public License for more details.
  19.  
  20. ;; You should have received a copy of the GNU General Public License
  21. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  22. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  
  24. ;;; Commentary:
  25.  
  26. ;; Load this and it will display highlighting on whatever
  27. ;; paren matches the one before or after point.
  28.  
  29. ;;; Code:
  30.  
  31. ;; This is the overlay used to highlight the matching paren.
  32. (defvar show-paren-overlay nil)
  33. ;; This is the overlay used to highlight the closeparen
  34. ;; right before point.
  35. (defvar show-paren-overlay-1 nil)
  36.  
  37. (defvar show-paren-mismatch-face nil)
  38.  
  39. ;; Find the place to show, if there is one,
  40. ;; and show it until input arrives.
  41. (defun show-paren-command-hook ()
  42.   (if window-system
  43.       (let (pos dir mismatch (oldpos (point))
  44.         (face 'region))
  45.     (cond ((eq (char-syntax (following-char)) ?\()
  46.            (setq dir 1))
  47.           ((eq (char-syntax (preceding-char)) ?\))
  48.            (setq dir -1)))
  49.     (if dir
  50.         (save-excursion
  51.           (save-restriction
  52.         ;; Determine the range within which to look for a match.
  53.         (if blink-matching-paren-distance
  54.             (narrow-to-region (max (point-min)
  55.                        (- (point) blink-matching-paren-distance))
  56.                       (min (point-max)
  57.                        (+ (point) blink-matching-paren-distance))))
  58.         ;; Scan across one sexp within that range.
  59.         (condition-case ()
  60.             (setq pos (scan-sexps (point) dir))
  61.           (error nil))
  62.         ;; See if the "matching" paren is the right kind of paren
  63.         ;; to match the one we started at.
  64.         (if pos
  65.             (let ((beg (min pos oldpos)) (end (max pos oldpos)))
  66.               (and (/= (char-syntax (char-after beg)) ?\$)
  67.                (setq mismatch
  68.                  (/= (char-after (1- end))
  69.                      (logand (lsh (aref (syntax-table)
  70.                             (char-after beg))
  71.                           -8)
  72.                          255))))))
  73.         ;; If they don't properly match, use a different face,
  74.         ;; or print a message.
  75.         (if mismatch
  76.             (progn
  77.               (and (null show-paren-mismatch-face)
  78.                (x-display-color-p)
  79.                (or (setq show-paren-mismatch-face
  80.                      (internal-find-face 'paren-mismatch))
  81.                    (progn
  82.                  (setq show-paren-mismatch-face
  83.                        (make-face 'paren-mismatch))
  84.                  (set-face-background 'paren-mismatch 'purple))))
  85.               (if show-paren-mismatch-face
  86.               (setq face show-paren-mismatch-face)
  87.             (message "Paren mismatch"))))
  88.         )))
  89.     (cond (pos
  90.            (if (= dir -1)
  91.            ;; If matching backwards, highlight the closeparen
  92.            ;; before point as well as its matching open.
  93.            (progn
  94.              (if show-paren-overlay-1
  95.              (move-overlay show-paren-overlay-1 (+ (point) dir) (point))
  96.                (setq show-paren-overlay-1
  97.                  (make-overlay (- pos dir) pos)))
  98.              (overlay-put show-paren-overlay-1 'face face))
  99.          ;; Otherwise, turn off any such highlighting.
  100.          (and show-paren-overlay-1
  101.               (overlay-buffer show-paren-overlay-1)
  102.               (delete-overlay show-paren-overlay-1)))
  103.            ;; Turn on highlighting for the matching paren.
  104.            (if show-paren-overlay
  105.            (move-overlay show-paren-overlay (- pos dir) pos)
  106.          (setq show-paren-overlay
  107.                (make-overlay (- pos dir) pos)))
  108.            (overlay-put show-paren-overlay 'face face))
  109.           (t
  110.            ;; If not at a paren that has a match,
  111.            ;; turn off any previous paren highlighting.
  112.            (and show-paren-overlay (overlay-buffer show-paren-overlay)
  113.             (delete-overlay show-paren-overlay))
  114.            (and show-paren-overlay-1 (overlay-buffer show-paren-overlay-1)
  115.             (delete-overlay show-paren-overlay-1)))))))
  116.  
  117. (if window-system
  118.     (progn
  119.       (setq blink-paren-function nil)
  120.       (add-hook 'post-command-hook 'show-paren-command-hook)))
  121.  
  122. (provide 'paren)
  123.  
  124. ;;; paren.el ends here
  125.